package rickyGame.controller
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	import ricky.game.Actor2D;
	import ricky.utils.TimeServer;
	
	import rickyGame.controller.state.AttackState;
	import rickyGame.controller.state.ManaState;
	import rickyGame.controller.state.MoveState;
	import rickyGame.controller.state.State;
	import rickyGame.controller.state.StopSate;
	import rickyGame.game.GameState;
	import rickyGame.game.Player;
	import rickyGame.game.scene.SceneManager;
	import rickyGame.game.skill.SkillData;
	import rickyGame.game.skill.SkillEffectTargetType;
	import rickyGame.net.MsgType;
	import rickyGame.net.WorkQueue;
	import rickyGame.net.handler.Handler;
	import rickyGame.ui.Cursor;
	import rickyGame.ui.pack.Grid;
	import rickyGame.ui.pack.Vessel;

	/**
	 * 游戏输入控制器
	 * @pu
	 * @date 2011.6.17
	 */
	public class Controller
	{
		public function Controller()
		{
			this._cursor=new Cursor();
			_state=new MoveState();
			manaState=new ManaState();
			attackState=new AttackState();
			stopState=new StopSate();
		}
		
		public function get pingEnable():Boolean
		{
			return _pingEnable;
		}

		public function set pingEnable(value:Boolean):void
		{
			_pingEnable = value;
		}

		public function get actor():Player
		{
			return _actor;
		}

		public function set actor(value:Player):void
		{
			_actor = value;
		}

		/**
		 * 初始化用户输入控制器
		 * 注册鼠标和键盘事件
		 */
		public function init(stage:Stage):void
		{
			_stage=stage;
			_stage.addEventListener(MouseEvent.MOUSE_UP,onMosueUp);
			_stage.addEventListener(MouseEvent.MOUSE_DOWN,onMosueDown);
			_stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
//			_stage.addEventListener(MouseEvent.CLICK,mouseClick);
			Cursor.register();
			Cursor.show(Cursor.NORMAL);
		}
		
		/**
		 * 点击地图
		 */
		public function mapClick(a:*):void
		{
			_state.operate(a);
		}
		
		/**
		 * 键按下
		 */
		public function keyDown(e:KeyboardEvent):void
		{
			if(e.keyCode==65)//a
			{
				switchSate(this.attackState);
			}
			else if(e.keyCode==Keyboard.ESCAPE)//esc
				switchSate(this.stopState);
			else if(e.keyCode>48 && e.keyCode<=57) //如果按了数字键0-9 48 -57
			{
				chooseSkill(e.keyCode-48);//e.keyCode-48);
			}else if(e.keyCode==Keyboard.TAB)//tab
			{
				var s:SceneManager=GameState.inst.sceneManager;
				if(s.miniMap)
				{
					if(s.miniMap.visible==true)
						s.miniMap.visible=false;
					else
						s.miniMap.visible=true;
				}
			}
			else
				switchSate(this.stopState);


		}
		
		public function updateEvent(e:Event=null):void
		{
			if(this._pingEnable)
				this.ping();
			
		}
		
		
		/**
		 * ping网络
		 */
		protected function ping():void
		{
			_now=TimeServer.now();
			_dt=_now-_lastTime;
			
			if(_dt>3000) //每两秒ping一次
			{
				_lastTime=_now;
				if(Handler.isPingSend)
					Handler.isPingSend=false;
				Handler.sendPing();
			}
		}
		
		
		/**
		 * 鼠标点击
		 */
		public function mouseClick(e:MouseEvent):void
		{
			//trace("鼠标盈动"+e.target);
			if(e.currentTarget is  Vessel)
			{
				var ves:Vessel=e.currentTarget as Vessel;
				if(ves.isfull)
				{
					var grid:Grid=ves.getChildAt(1) as Grid; 
					grid.operate(null);	
				}
			}
			
//			JDebug.trace(e.target);
//			JDebug.trace("点击："+e.stageX,e.stageY);
		}
		
		/**
		 * 鼠标移动事件
		 */
		public function mouseMove(e:MouseEvent):void
		{
			this.cursor.x=e.stageX;
			this.cursor.y=e.stageY;
			this.cursor.parent.setChildIndex(this.cursor,this._cursor.parent.numChildren-1);
		}
		
		/**
		 * 按下鼠标
		 */
		public function onMouseDown(e:MouseEvent):void
		{
			if(e.currentTarget is  Vessel && !_isdragging)
			{
				var ves:Vessel=e.currentTarget as Vessel;
				
				if(ves.isfull)
				{
					var grid:Grid=ves.getChildAt(1) as Grid;			
					grid.oldParent=grid.parent;				
//					_offX=grid.width/2;
//					_offY=grid.height/2;				
					_isdragging=true;
					_target=grid;
					grid.visible=false;
					
					var sX:Number=e.stageX;
					var sY:Number=e.stageY;			
					this.stage.addChild(_target);
					_target.x=sX-_offX;
					_target.y=sY-_offY;
					_target.visible=true;
				}
			}
			
		}
		
		/**
		 * 鼠标按起
		 */
		public function onMosueDown(e:MouseEvent):void
		{
			
		}
		/**
		 * 鼠标按起
		 */
		public function onMosueUp(e:MouseEvent):void
		{
			_isdragging=false;			
			//			trace("不拖动了"+e.target+"currentTarget="+e.currentTarget+""+e.relatedObject);
			
			var grid:Grid=(_target as  Grid);		
			
			if(_container && grid!=null && _container.addChild(_target)!=null)
			{
				_target.x=0;
				_target.y=0;
			}
			else if(grid)
			{
				grid.oldParent.addChild(grid);
				grid.x=0;
				grid.y=0;
			}
			_target=null;
			_container=null;
		}
		
		/**
		 * 鼠标移动
		 */
		public function onMouseMove(x:Number,y:Number):void//e:MouseEvent
		{
			if(this._target)
			{
				//				trace("全局座标:"+e.stageX+":"+e.stageY);e.stageX
				_target.x=x-_offX;
				_target.y=y-_offY;
				//				var g:Point=new Point(e.localX,e.localY);
				//				var l:Point=_target.globalToLocal(g);
				//				trace("本地座标:"+l);
				//				_target.x=l.x-_offX;
				//				_target.y=l.y-_offY;
			}
			
		}
		
//		/**
//		 * 鼠标移动到上面
//		 */
//		public function onMouseOver(e:MouseEvent):void
//		{
//			trace("onMouseOver 容器:"+e.currentTarget+"目标"+this._target);
//			if(this._target!=null && e.currentTarget is Vessel)
//			{
//				_container=e.currentTarget as  DisplayObjectContainer;
//				trace("找到容器了");
//			}
//			
//		}
//		
//		/**
//		 * 鼠标移动除
//		 */
//		public function onMouseOut(e:MouseEvent):void
//		{
//			_container=null;
//			//trace("容器没了");
//		}
		
		/////////////////////////////////////////////
		//
		////////////////////////////////////////////////
		
		public function chooseSkill(i:int):void
		{
//			var me:Player=GameState.inst.me;

			var learned:Array=_actor.skills.learned;
			if(learned.length>=i && i>0)
			{
				var sk:rickyGame.game.skill.SkillData=learned[i-1];//GameState.inst.me.skillList.currSkill;
				if(sk.effectTarget.indexOf(SkillEffectTargetType.self)>=0 && sk.spellTarget.indexOf(SkillEffectTargetType.self)>=0)
				{
					var p:Point=new Point(_actor.graphic.x,_actor.graphic.y);
//					WorkQueue.instance.pushRecive(MsgType.SERVER_ABILITY_ATTACKTARGET,me,sk.abilityID,p,me);//同步目标对象
				}else
				{
					_actor.skills.currSkill=sk;
					switchSate(this.manaState);
				}
			}
		}
		
		private var manaState:ManaState;
		private var attackState:AttackState;
		private var stopState:StopSate;
		/////////////////////////////////
		//
		//////////////////////////////
		/**
		 * 托动的对像
		 */
		public function get target():DisplayObject
		{
			return _target;
		}
		
		/**
		 * 对像要放入的容器
		 */
		public function get container():DisplayObjectContainer
		{
			return _container;
		}
		
		public function get stage():Stage
		{
			return _stage;
		}
		/**
		 * 选择状态
		 */
		public function switchSate(state:State):void
		{
			_state=state;
			_state.create();
		}
		
		private var _state:State;//当前状态
		
		private var _cursor:Cursor;
		
		private static var _instance:Controller;

		public static function get instance():Controller
		{
			if(_instance==null)
				_instance=new Controller();
			return _instance;
		}

		public function get cursor():Cursor
		{
			return _cursor;
		}

		public function set cursor(value:Cursor):void
		{
			_cursor = value;
		}

		private var _stage:Stage;

		private var _isdragging:Boolean=false;
		private var _target:DisplayObject;
		private var _container:DisplayObjectContainer;
		private var _offX:Number=0;		
		private var _offY:Number=0;
		private var _pingEnable:Boolean=false;
		private var _actor:Player;
		
		//
		private var _lastTime:Number=0;
		private var _dt:Number=0;
		private var _now:Number=0;

	}
}